package com.lframework.jh.push.api.listeners;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lframework.jh.push.api.utils.SmsChannelUtil;
import com.lframework.jh.push.core.components.mq.MqProducer;
import com.lframework.jh.push.core.constants.MqConstants;
import com.lframework.jh.push.plugin.core.SmsPushChannel;
import com.lframework.jh.push.plugin.core.dto.NotifySmsBatchDto;
import com.lframework.jh.push.plugin.core.dto.QuerySmsPushResultDetailDto;
import com.lframework.jh.push.plugin.core.dto.QuerySmsPushResultDetailRespDto;
import com.lframework.jh.push.service.entity.PushOrder;
import com.lframework.jh.push.service.entity.SmsBatchDetail;
import com.lframework.jh.push.service.enums.PushOrderStatus;
import com.lframework.jh.push.service.enums.SmsBatchDetailStatus;
import com.lframework.jh.push.service.service.PushOrderService;
import com.lframework.jh.push.service.service.SmsBatchDetailService;
import java.time.LocalDateTime;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class QuerySmsPushResultDetailListener {

    @Autowired
    private SmsBatchDetailService smsBatchDetailService;

    @Autowired
    private MqProducer mqProducer;

    @Autowired
    private PushOrderService pushOrderService;

    @JmsListener(destination = MqConstants.QUEUE_QUERY_SMS_PUSH_RESULT_DETAIL)
    public void execute(QuerySmsPushResultDetailDto dto) throws Exception {
        try {
            log.info("【第二步】（明细方式）接收到异步查询短信推送结果请求 dto {}", dto);

            SmsPushChannel channel = SmsChannelUtil.getByChannel(dto.getChannel());
            QuerySmsPushResultDetailRespDto resp = channel.query(dto);
            log.info("【第二步】（明细方式）异步查询短信通知推送结果 resp {}", resp);
            if (resp == null) {
                this.doRetry(dto);
                return;
            }
            if (resp.getStatus() == 2) {
                Wrapper<SmsBatchDetail> updateWrapper = Wrappers.lambdaUpdate(SmsBatchDetail.class)
                    .eq(SmsBatchDetail::getBatchNo, dto.getBatchNo())
                    .eq(SmsBatchDetail::getPhoneNumber, dto.getPhoneNumber())
                    .set(SmsBatchDetail::getErrorMsg, resp.getErrorMsg())
                    .set(SmsBatchDetail::getStatus, SmsBatchDetailStatus.FAIL);
                smsBatchDetailService.update(updateWrapper);

                this.doNotifyDto(dto, false);
            } else if (resp.getStatus() == 3) {
                Wrapper<SmsBatchDetail> updateWrapper = Wrappers.lambdaUpdate(SmsBatchDetail.class)
                    .eq(SmsBatchDetail::getBatchNo, dto.getBatchNo())
                    .eq(SmsBatchDetail::getPhoneNumber, dto.getPhoneNumber())
                    .set(SmsBatchDetail::getStatus, SmsBatchDetailStatus.SUCCESS)
                    .set(SmsBatchDetail::getSuccessTime, resp.getSuccessTime())
                    .set(SmsBatchDetail::getSmsContent, resp.getContent());
                smsBatchDetailService.update(updateWrapper);

                this.doNotifyDto(dto, true);
            } else {
                this.doRetry(dto);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            this.doRetry(dto);
        }
    }

    private void doRetry(QuerySmsPushResultDetailDto dto) {
        if (dto.getCurIndex() < MqConstants.SMS_ASYNC_QUERY_RETRY_SECONDS.length - 1) {
            log.info("【第二步】（明细方式）重试异步查询短信推送结果 dto {}", dto);
            dto.setCurIndex(dto.getCurIndex() + 1);
            mqProducer.sendDelayMessage(MqConstants.QUEUE_QUERY_SMS_PUSH_RESULT_DETAIL, dto,
                MqConstants.SMS_ASYNC_QUERY_RETRY_SECONDS[dto.getCurIndex()] * 1000L);
        } else {
            log.info("【第二步】（明细方式）不再重试异步查询短信推送结果，原因：重试次数过多。dto {}",
                dto);
        }
    }

    private void doNotifyDto(QuerySmsPushResultDetailDto dto, boolean success) {
        // 这里先查一下是否还有未查批次结果的明细记录
        Wrapper<SmsBatchDetail> queryWrapper = Wrappers.lambdaQuery(SmsBatchDetail.class)
            .eq(SmsBatchDetail::getBatchNo, dto.getBatchNo())
            .eq(SmsBatchDetail::getStatus, SmsBatchDetailStatus.CREATED).last("LIMIT 1");
        SmsBatchDetail smsBatchDetail = smsBatchDetailService.getOne(queryWrapper);
        if (smsBatchDetail == null) {
            //所有的批次结果都查询过了
            PushOrder record = new PushOrder();
            record.setId(dto.getOrderId());
            record.setStatus(PushOrderStatus.SUCCESS);
            record.setSuccessTime(LocalDateTime.now());
            pushOrderService.updateById(record);
        }

        NotifySmsBatchDto notifySmsBatchDto = new NotifySmsBatchDto();
        notifySmsBatchDto.setOrderId(dto.getOrderId());
        notifySmsBatchDto.setBatchNo(dto.getBatchNo());
        notifySmsBatchDto.setPhoneNumber(dto.getPhoneNumber());
        notifySmsBatchDto.setSuccess(success);

        mqProducer.sendMessage(MqConstants.QUEUE_NOTIFY_SMS_BATCH, notifySmsBatchDto);
    }
}
